#include "key.h"
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>


// PE8 9 10 11  ROW1 ROW2 ROW3 ROW4
// PE12 13 14 15 COL1 COL2 COL3 COL4
//#define ROW1 GPIO_PIN_8
//#define ROW2 GPIO_PIN_9
//#define ROW3 GPIO_PIN_10
//#define ROW4 GPIO_PIN_11
//#define COL1 GPIO_PIN_12
//#define COL2 GPIO_PIN_13
//#define COL3 GPIO_PIN_14
//#define COL4 GPIO_PIN_15
//#define LED_SW GPIO_PIN_6
//#define LED1 GPIO_PIN_8
//#define LED2 GPIO_PIN_9
//#define LED3 GPIO_PIN_10
//#define LED4 GPIO_PIN_11
//#define LED5 GPIO_PIN_12
//#define LED6 GPIO_PIN_13
//#define LED7 GPIO_PIN_14
//#define LED8 GPIO_PIN_15

void gpio_led_config()
{
	rcu_periph_clock_enable(RCU_GPIOC);
	rcu_periph_clock_enable(RCU_GPIOD);
	
	gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_SW);
	gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED1);
	gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED2);
	gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED3);
	gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED4);
	gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED5);
	gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED6);
	gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED7);
	gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED8);
	
	gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED_SW);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED1);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED2);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED3);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED4);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED5);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED6);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED7);
	gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED8);
	
	gpio_bit_reset(GPIOC, GPIO_PIN_6);	// 打开LED的开关（低电平导通）
}

// 行做输出（推挽），列做输入（上拉），检测列
void gpio_rowout_colin()
{
	// 1. 初始化时钟
	rcu_periph_clock_enable(RCU_GPIOE);
	// 2. 输出模式 行输出推挽
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ROW1);
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ROW2);
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ROW3);
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ROW4);
	// 3. 输入模式 列做输入  GPIO_PUPD_PULLUP 表示上拉输入
	gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, COL1);
	gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, COL2);
	gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, COL3);
	gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, COL4);
	
	// 4. 行输出做推挽
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, ROW1);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, ROW2);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, ROW3);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, ROW4);
}

// 行做输入（上拉），列做输出（推挽），检测行
void gpio_rowin_colout()
{
	// 1. 初始化时钟
	rcu_periph_clock_enable(RCU_GPIOE);
	// 2. 输出模式 列输出推挽
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, COL1);
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, COL2);
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, COL3);
	gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, COL4);
	// 3. 输入模式 行做输入  GPIO_PUPD_PULLUP 表示上拉输入
	gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, ROW1);
	gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, ROW2);
	gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, ROW3);
	gpio_mode_set(GPIOE, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, ROW4);
	
	// 4. 列输出做推挽
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, COL1);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, COL2);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, COL3);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, COL4);
}


void led_running(uint8_t row, uint8_t col)
{
	if (row == 1)
	{
		switch(col)
		{
			case 1:
				gpio_bit_reset(GPIOD, LED1);	// 点亮LED1（低电平亮灯）
				break;
			case 2:
				gpio_bit_reset(GPIOD, LED2);	// 点亮LED2（低电平亮灯）
				break;
			case 3:
				gpio_bit_reset(GPIOD, LED3);	// 点亮LED3（低电平亮灯）
				break;
			case 4:
				gpio_bit_reset(GPIOD, LED4);	// 点亮LED4（低电平亮灯）
				break;
		}
	}
	if (row == 2)
	{
		switch(col)
		{
			case 1:
				gpio_bit_reset(GPIOD, LED5);	// 点亮LED5（低电平亮灯）
				break;
			case 2:
				gpio_bit_reset(GPIOD, LED6);	// 点亮LED6（低电平亮灯）
				break;
			case 3:
				gpio_bit_reset(GPIOD, LED7);	// 点亮LED7（低电平亮灯）
				break;
			case 4:
				gpio_bit_reset(GPIOD, LED8);	// 点亮LED8（低电平亮灯）
				break;
		}
	}
	
	if (row == 3)
	{
		switch(col)
		{
			case 1:
				gpio_bit_reset(GPIOD, LED8);	// 点亮LED5（低电平亮灯）
				break;
			case 2:
				gpio_bit_reset(GPIOD, LED7);	// 点亮LED6（低电平亮灯）
				break;
			case 3:
				gpio_bit_reset(GPIOD, LED6);	// 点亮LED7（低电平亮灯）
				break;
			case 4:
				gpio_bit_reset(GPIOD, LED5);	// 点亮LED8（低电平亮灯）
				break;
		}
	}
	
	if (row == 4)
	{
		switch(col)
		{
			case 1:
				gpio_bit_reset(GPIOD, LED4);	// 点亮LED5（低电平亮灯）
				break;
			case 2:
				gpio_bit_reset(GPIOD, LED3);	// 点亮LED6（低电平亮灯）
				break;
			case 3:
				gpio_bit_reset(GPIOD, LED2);	// 点亮LED7（低电平亮灯）
				break;
			case 4:
				gpio_bit_reset(GPIOD, LED1);	// 点亮LED8（低电平亮灯）
				break;
		}
	}
}

void LED_OFF()
{
	gpio_bit_set(GPIOD, LED1);		// 高电平灭灯
	gpio_bit_set(GPIOD, LED2);		// 高电平灭灯
	gpio_bit_set(GPIOD, LED3);		// 高电平灭灯
	gpio_bit_set(GPIOD, LED4);		// 高电平灭灯
	gpio_bit_set(GPIOD, LED5);		// 高电平灭灯
	gpio_bit_set(GPIOD, LED6);		// 高电平灭灯
	gpio_bit_set(GPIOD, LED7);		// 高电平灭灯
	gpio_bit_set(GPIOD, LED8);		// 高电平灭灯
}

int demo(void)
{
		uint8_t row_state;
		uint8_t col_state;
		// 系统滴答定时器配置（必须存在）
    systick_config();
		
		// 初始化LED灯的电路
		gpio_led_config();

    while(1) 
		{
			gpio_rowout_colin();		// 先判断列（行出列入） 电平是0表示列中有按键按下
			if (gpio_input_bit_get(GPIOE, COL1) == 0)
			{		// 第一列有按键按下
					col_state = 1;
			}else if (gpio_input_bit_get(GPIOE, COL2) == 0)
			{
					col_state = 2;
			}else if (gpio_input_bit_get(GPIOE, COL3) == 0)
			{
					col_state = 3;
			}else if (gpio_input_bit_get(GPIOE, COL4) == 0)
			{
					col_state = 4;
			}else 
			{
					row_state = 0;
					col_state = 0;
					LED_OFF();
					continue;
			}
			
			gpio_rowin_colout();		// 判断行（行入列出）
			
			if (gpio_input_bit_get(GPIOE, ROW1) == 0)
			{		// 第一列有按键按下
					row_state = 1;
			}else if (gpio_input_bit_get(GPIOE, ROW2) == 0)
			{
					row_state = 2;
			}else if (gpio_input_bit_get(GPIOE, ROW3) == 0)
			{
					row_state = 3;
			}else if (gpio_input_bit_get(GPIOE, ROW4) == 0)
			{
					row_state = 4;
			}else 
			{
					row_state = 0;
					col_state = 0;
					LED_OFF();
					continue;
			}
			
			led_running(row_state, col_state);
    }
}
